package com.example.stockservice.controller;


import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.example.stockservice.service.FeignClientService.TbProductsFeignClientService;
import com.example.stockservice.service.ITbProductstocksService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.util.List;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author xujk
 * @since 2021-11-23
 */
@Slf4j
@RestController
@RequestMapping("/tb-products")
public class TbProductsController {
    //region springboot method
    @NacosInjected
    private NamingService namingService;

    @ApiOperation(value="获取服务")
    @RequestMapping(value = "/get", method = GET)
    @ResponseBody
    public List<Instance> get(@RequestParam String serviceName) throws NacosException {
        return namingService.getAllInstances(serviceName);
    }
    //endregion

    //region spring cloud Method
    private final RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @Autowired
    public TbProductsController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

    @ApiOperation(value="获取订单信息")
    @RequestMapping(value = "/GetOrder/{str}", method = RequestMethod.GET)
    public String getOrder(@PathVariable String str) {
        // 通过的负载均衡接口获取服务实例信息
        ServiceInstance serviceInstance = loadBalancerClient.choose("orderservice");
        String url = "http://" + serviceInstance.getServiceId() + ":" + serviceInstance.getPort() + "/tb-orders/GetOrder?orderId="+str;
        log.info(url);
        return restTemplate.getForObject(url, String.class);
    }
    //endregion

    //region DiscoveryClient Method
    /*@Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private LoadBalancer loadBalancer;

    @ApiOperation(value="获取订单信息1")
    @RequestMapping(value = "/GetOrder1/{str}", method = RequestMethod.GET)
    public String getOrder1(@PathVariable String str)
    {
        // 1.根据服务名称从 注册中心获取集群列表地址
        List<ServiceInstance> instances = discoveryClient.getInstances("orderservice");

        // 2.列表任意选择一个 实现本地rpc调用 rest 采用我们负载均衡的算法
        ServiceInstance srviceInstance = loadBalancer.getSingleAddres(instances);

        URI rpcMemberUrl = srviceInstance.getUri();
        String result = restTemplate.getForObject(rpcMemberUrl + "/getUser", String.class);

        return "订单调用会员返回结果是: " + result;
    }*/
    //endregion

    //region 基于Ribbon实现本地负载均衡
    /**
     *
     * 基于Ribbon实现本地负载均衡
     *
     * @return[参数说明] @return Object[返回类型说明]
     * @exception throws
     *                [违例类型][违例说明]
     * @see [类、类#方法、类#成员]
     */
    @ApiOperation(value="获取订单信息Ribbon")
    @RequestMapping(value = "/GetOrderToRibbonMember/{str}", method = RequestMethod.GET)
    public Object orderToRibbonMember(@PathVariable String str)
    {
        String result = restTemplate.getForObject("http://orderservice/tb-orders/GetOrder?orderId="+str, String.class);
        return "Ribbon实现本地负载均衡，库存调用订单返回结果:" + result;
    }
    //endregion

    //region OpenFeign
    @Resource
    TbProductsFeignClientService productService;

    @ApiOperation(value="获取订单信息OpenFeign")
    @GetMapping("/get/{id}")
    public Object selectById(@PathVariable("id") Long id){
        return productService.selectById(id);
        /*return new Result(200, "查询成功",
                restTemplate.getForObject(url+"product/provider/get/"+id, Result.class));*/
    }
    //endregion
}

